/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */


import JaCoP.core.Store;
import JaCoP.core.Variable;
import JaCoP.search.IndomainMin;
import JaCoP.search.MostConstrainedStatic;
import JaCoP.search.Search;
import JaCoP.search.SelectChoicePoint;
import JaCoP.search.SimpleSelect;
import java.util.ArrayList;
/**
 *
 * @author Administrator
 */
public class MostConstrainedSeacher implements Searcher {

    Search search;
    ArrayList<Variable> vars;
    Store store;
    private long time;
    private boolean solution=true;


/**
 * It returns all soultion as String e.g  2 9 8 2 3
 * @return Return all soultions as String
 */
    public String getAllSolution()
    {
        StringBuffer buff = new StringBuffer();

        for (int i=1; i<=search.getSolutionListener().solutionsNo(); i++) {
		      for (int j=0; j<search.getSolution(i).length; j++)
		         buff.append(" "+search.getSolution(i)[j]);
		      buff.append("\n");
		   }
        return buff.toString();
    }

    /**
     *
     * @return execution time
     */
    public long time()
    {
        return this.time;
    }

/**
 *
 * @param vars arralist of Variable
 * @param store Store that contains information about Variables and constrains
 */
    public MostConstrainedSeacher(ArrayList<Variable> vars, Store store)
  {
        this.vars = vars;
        this.store = store;
  }

    /**
     *
     * @return number of solution
     */
    public int getNoSolution()
    {
        return search.getSolutionListener().solutionsNo();
    }

    /**
     *
     * @return number of backtrack
     */
    public int getBackTrack()
    {
        return search.getBacktracks();
    }

    /**
     *
     * @return number of nodes
     */
    public int getNodes()
    {
        return search.getNodes();
    }

    /**
     *
     * @return number of decisions
     */
    public int getDecision()
    {
        return search.getDecisions();
    }

    /**
     *
     * @return number of wrong decisions
     */
    public int getWrongDecision()
    {
        return search.getWrongDecisions();
    }

    /**
     *
     * @return number of diffrent letters used in Cryptarithm
     */
    public int getNumberLitteral()
    {
        return vars.size();
    }

    /**
     *
     * @return Return all letters in cryptarithm
     */
    public String printDifrentChar()
    {
        StringBuffer charString = new StringBuffer();
        for(int i=0;i<vars.size();i++)
        {
            charString.append(vars.get(i).id + " ");

        }
        charString.append("\n");
        return charString.toString();
    }
    /**
     *
     * @return maximum depth
     */
    public int getMaximumDepth()
    {
        return search.getMaximumDepth();
    }

    /**
     * It specifies simple search method based variable order which
     * takes into account the number of constraints attached to a variable
     * and lexigraphical ordering of values. 
     * @return true if there is a solution, false otherwise
     */
    public boolean search() {

		search = new DepthFirstSearchWithoutPrintingSolution();
		long t1=System.currentTimeMillis();
		SelectChoicePoint select = new SimpleSelect(vars.toArray(new Variable[1]),
				new MostConstrainedStatic(), new IndomainMin());

		search.getSolutionListener().searchAll(true);
		search.getSolutionListener().recordSolutions(true);
		boolean result = search.labeling(store, select);

		long t2=System.currentTimeMillis();
                time=t2-t1;

		if (!result)
			solution=false;

		return result;

	}
}
